'use strict'
const path = require('path')
const cp = require('child_process')
const log = require('@imooc-yishen-cli-dev/log')
const Package = require('@imooc-yishen-cli-dev/package')

module.exports = exec

const SETTINGS = {
  init: '@imooc-cli/init',
}

const CACHE_DIR = 'dependencies'

// init action 调用这个函数。参数不定长。
async function exec() {
  let targetPath = process.env.CLI_TARGET_PATH
  const homePath = process.env.CLI_HOME_PATH
  let storeDir = ''
  let pkg
  log.verbose('targetPath', targetPath)
  log.verbose('homePath', homePath)
  const cmdObj = arguments[arguments.length - 1]
  const cmdName = cmdObj.name()
  const packageName = SETTINGS[cmdName]
  const packageVersion = 'latest'

  if (!targetPath) {
    targetPath = path.resolve(homePath, CACHE_DIR) // 生成缓存路径
    storeDir = path.resolve(homePath, 'node_modules')
    pkg = new Package({ targetPath, storeDir, packageName, packageVersion })
    if (await pkg.exists()) {
      pkg.update()
    } else {
      await pkg.install()
    }
  } else {
    pkg = new Package({ targetPath, packageName, packageVersion })
  }
  const rootFile = pkg.getRootFilePath()
  // apply 的作用。
  // require(rootFile) 引入的是 commands/init/lib/index.js 中 init
  // init 需要参数是参数列表。而 arguments 是一个数组。
  if (rootFile) {
    try {
      // require(rootFile).call(null, Array.from(arguments));
      // 在node子进程中调用
      const args = Array.from(arguments);
      const cmd = args[args.length - 1];
      const o = Object.create(null);
      Object.keys(cmd).forEach(key => {
        if (cmd.hasOwnProperty(key) &&
          !key.startsWith('_') &&
          key !== 'parent') {
          o[key] = cmd[key];
        }
      });
      args[args.length - 1] = o;
      const code = `require('${rootFile}').call(null, ${JSON.stringify(args)})`;
      const child = cp.spawn('node', ['-e', code], {
        cwd: process.cwd(),
        stdio: 'inherit',
      });
      child.on('error', e => {
        log.error(e.message);
        process.exit(1);
      });
      child.on('exit', e => {
        log.verbose('命令执行成功:' + e);
        process.exit(e);
      });
    } catch (e) {
      log.error(e.message);
    }
  }
}
